package com.cheryjb.examples.gwt.clock.client;

import java.util.Date;

import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.i18n.shared.DateTimeFormat;

/**
 * This is the clock object that is a composite of several drawable objects: the
 * clock frame and the three needles (hours, minutes, seconds)
 * 
 * @author Jean-Baptiste Chery
 * 
 */
public class Clock {

	/**
	 * Clock Frame Drawable object
	 */
	private final ClockFrame clockFrame;

	/**
	 * Needle that shows the hours
	 */
	private final Needle hoursNeedle;

	/**
	 * Needle that shows the minutes
	 */
	private final Needle minutesNeedle;

	/**
	 * Needle that shows the seconds
	 */
	private final Needle secondsNeedle;

	/**
	 * instantiate the Drawable Objects
	 */
	public Clock() {
		// component objects
		clockFrame = new ClockFrame(new Vector(0, 0));
		secondsNeedle = new Needle(new Vector(10, 15), NeedleType.SECONDS,
				new Vector(105, 99));
		minutesNeedle = new Needle(new Vector(18, 24), NeedleType.MINUTES,
				new Vector(97, 90));
		hoursNeedle = new Needle(new Vector(31, 38), NeedleType.HOURS,
				new Vector(84, 76));
	}

	/**
	 * Draw each Drawable Object
	 * 
	 * @param context
	 */
	public void draw(final Context2d context) {
		clockFrame.draw(context);
		hoursNeedle.draw(context);
		minutesNeedle.draw(context);
		secondsNeedle.draw(context);
	}

	/**
	 * Update the needles based on the date given in parameters. It extracts the
	 * hours/minutes/seconds and update the rotation angle of each object
	 * 
	 * @param date
	 *            Time that clock will display
	 */
	public void update(final Date date) {
		// extract hours/minutes/seconds from the date
		final DateTimeFormat secondFormat = DateTimeFormat.getFormat("s");
		final DateTimeFormat minuteFormat = DateTimeFormat.getFormat("m");
		final DateTimeFormat hourFormat = DateTimeFormat.getFormat("h");
		final int seconds = Integer.valueOf(secondFormat.format(date));
		final int minutes = Integer.valueOf(minuteFormat.format(date));
		final int hours = Integer.valueOf(hourFormat.format(date));

		// 60 seconds = 360 degrees ; 1 second = 6 degrees ; x seconds = x * 6
		// degrees
		// 6d is the notation for (double) 6
		secondsNeedle.setRotationDeg(seconds * 6d);

		// 60 minutes = 360 degrees ; 1 minute = 6 degrees ; x minutes = x * 6
		// degrees
		// 6d is the notation for (double) 6
		minutesNeedle.setRotationDeg(minutes * 6d);

		// 12 hours = 360 degrees ; 1 hour = 30 degrees ; x hours = x * 6
		// degrees
		// 30d is the notation for (double) 30
		hoursNeedle.setRotationDeg(hours * 30d);
	}
}
